﻿//===========================================================================================================================
// Cuberry - http://www.cuberry.net
// Copyright (c) 2012
// by Peacequare® - Amir Moussa
//===========================================================================================================================
// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 
// as published by the Free Software Foundation, either version 3 of the License, or any later version.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// This program is distributed in the hope that it will be useful.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//===========================================================================================================================

using System;
using System.Collections.Generic;
using System.Linq;
using P2.Cuberry.Framework.Helper;


namespace P2.Cuberry.Framework.Security
{
    public class User
    {
        static string connectionString = P2.Cuberry.Framework.Helper.Configuration.ConfigurationSetUp.GetEntConnectionString("Security", P2.Cuberry.Framework.Helper.Properties.Settings.Default.EntityResourcesSecurity);

        public string UserID { get; set; }
        public int UserGroupID { get; set; }
        public bool Active { get; set; }
        public string UserGroupName { get; set; }
        
        protected User()
        { }


        public User(string userID)
        {
            FillMyObject(userID);
        }


        protected void FillMyObject(string userID)
        {
            try
            {
                using (P2.Cuberry.Framework.Helper.DAL.SecurityDataClassesDataContext db = new P2.Cuberry.Framework.Helper.DAL.SecurityDataClassesDataContext(connectionString))
                {
                    this.UserID = userID;
                    var users = from usr in db.XSecUser
                                where usr.UserID == userID
                                select new { usr.UserID, usr.UserGroupID, usr.Active };

                    if (users.Count() <= 0)
                    {
                        this.UserGroupID = -1;
                        this.UserGroupName = P2Translator.GetResource("NewUser");
                        this.Active = false;
                    }
                    else
                    {
                        var firstUser = users.First();
                        this.UserID = firstUser.UserID;
                        if (firstUser.UserGroupID.HasValue && firstUser.UserGroupID.Value >= 0)
                        {
                            var groups = from ug in db.XSecUserGroup
                                         where ug.UserGroupID == firstUser.UserGroupID.Value
                                         && (ug.Active != null && ug.Active == true)
                                         select ug;
                            if (groups.Count() > 0)
                            {
                                this.UserGroupID = firstUser.UserGroupID.Value;
                                this.UserGroupName = groups.First().UserGroupName;
                            }
                            else
                            {
                                this.UserGroupID = -1;
                                this.UserGroupName = P2Translator.GetResource("InvalidGroup");
                            }
                        }
                        else
                            this.UserGroupID = -1;
                        this.Active = firstUser.Active;
                    }
                }
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", this.GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name));
            }
        }


        protected static User _current = null;
        public static User Current
        {
            get
            {
                if (_current == null)
                {
                    _current = new User(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
                    P2Log.LogUserLogin(Environment.UserName.ToString(), Environment.UserDomainName.ToString(), Environment.OSVersion.ToString(), Environment.MachineName.ToString(), true);
                }
                return _current;
            }
        }


        string moduleNameCached = null;
        string dialogNameCached = null;


        Dictionary<string, ControlRight> _controlsCached = null;
        public Dictionary<string, ControlRight> GetControls(string ModuleName, string DialogName, P2.Cuberry.Framework.Helper.Workflows.WorkflowStatus workflowStatus)
        {
            try
            {
                var wfControls = workflowStatus.GetWorkflowControls(ModuleName, DialogName);
                if (1 == 1 || _controlsCached == null || moduleNameCached == null || dialogNameCached == null || moduleNameCached != ModuleName || dialogNameCached != DialogName)
                {
                    this._controlsCached = new Dictionary<string, ControlRight>();
                    this.moduleNameCached = ModuleName;
                    this.dialogNameCached = DialogName;
                    int moduleAccessRight = 0;
                    using (P2.Cuberry.Framework.Helper.DAL.SecurityDataClassesDataContext db = new P2.Cuberry.Framework.Helper.DAL.SecurityDataClassesDataContext(connectionString))
                    {
                        var arItems = from ar in db.XSecUserRights
                                      where ar.ModuleName == ModuleName
                                      && ar.UserGroupID == this.UserGroupID
                                      select ar.AccessRight
                                      ;

                        foreach (var arItem in arItems)
                        {
                            moduleAccessRight = arItem;
                        }
                        arItems = null;

                        var ucItems = from uc in db.XConfigUIControls
                                      where uc.ModuleName == ModuleName && uc.DialogName == DialogName
                                      select new { uc.ControlName, uc.IsActive }
                                                      ;

                        var arcItemsAll = from arc in db.XSecUserRightsSpecial
                                          where arc.UserGroupID == this.UserGroupID
                                          && arc.ModuleName == ModuleName
                                          && arc.DialogName == DialogName
                                          && (arc.StatusID == 0)
                                          select new { arc.ControlName, arc.AccessRight, arc.StatusID };

                        var arcItemsStat = from arc in db.XSecUserRightsSpecial
                                           where arc.UserGroupID == this.UserGroupID
                                           && arc.ModuleName == ModuleName
                                           && arc.DialogName == DialogName
                                           && (arc.StatusID == workflowStatus.StatusID)
                                           select new { arc.ControlName, arc.AccessRight, arc.StatusID };


                        var arcDictAll = arcItemsAll.ToDictionary(k => k.ControlName);
                        var arcDictStat = arcItemsStat.ToDictionary(k => k.ControlName);

                        foreach (var ucItem in ucItems)
                        {

                            if (moduleAccessRight < 2)
                            {
                                _controlsCached[ucItem.ControlName] = new ControlRight() { ControlName = ucItem.ControlName, DialogName = DialogName, ModuleName = ModuleName, IsActive = false };
                            }
                            else
                            {
                                bool isActive = ucItem.IsActive.GetValueOrDefault(false);
                                if (wfControls.ContainsKey(ucItem.ControlName))
                                    isActive = wfControls[ucItem.ControlName].IsActive;
                                if (!workflowStatus.EndStatus)
                                {
                                    if (arcDictStat.ContainsKey(ucItem.ControlName))
                                    {
                                        isActive = 0 < arcDictStat[ucItem.ControlName].AccessRight.GetValueOrDefault(0) ? true : false;

                                    }
                                    else
                                    {
                                        if (arcDictAll.ContainsKey(ucItem.ControlName))
                                        {
                                            isActive = 0 < arcDictAll[ucItem.ControlName].AccessRight.GetValueOrDefault(0) ? true : false;
                                        }
                                    }
                                }
                                _controlsCached[ucItem.ControlName] = new ControlRight() { ControlName = ucItem.ControlName, DialogName = DialogName, ModuleName = ModuleName, IsActive = isActive };

                            }
                        }
                    }
                }
                return _controlsCached;
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", this.GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name));
                return null;
            }
        }


        public class ControlRight
        {
            public string ModuleName { get; set; }
            public string DialogName { get; set; }
            public string ControlName { get; set; }
            public bool IsActive { get; set; }
        }


    }
}
